package model.entities;

import java.awt.Color;

public class Mirror implements IEntity {
	
	private static final MirrorOrientation DEFAULT_ORIENTATION = MirrorOrientation.VERTICAL;
	
	private MirrorOrientation mirrorOrientation;
	private boolean orientationLocked = false;
	
	public Mirror() {
		this.mirrorOrientation = DEFAULT_ORIENTATION;
	}
	
	public Mirror(MirrorOrientation mirrorOrientation) {
		this.mirrorOrientation = mirrorOrientation;
	}

	@Override
	public Direction handleLaserBeam(Direction inDirection, Color beamColor) {
		
		switch (inDirection) {
	
		case TOP :
			
			switch (mirrorOrientation) {
		
			case VERTICAL :
				return null;
			case HORIZONTAL :
				return Direction.TOP;
			case POSITIVE_SLOPE :
				return Direction.LEFT;
			case NEGATIVE_SLOPE :
				return Direction.RIGHT;
			case SLIGHT_RISE :
				return Direction.TOP_LEFT;
			case SLIGHT_DECLINE :
				return Direction.TOP_RIGHT;
			case STEEP_RISE :
				return Direction.BOTTOM_LEFT;
			case STEEP_DECLINE :
				return Direction.BOTTOM_RIGHT;
			}
			
		case TOP_RIGHT :
			
			switch (mirrorOrientation) {
		
			case VERTICAL :
				return Direction.BOTTOM_RIGHT;
			case HORIZONTAL :
				return Direction.TOP_LEFT;
			case POSITIVE_SLOPE :
				return null;
			case NEGATIVE_SLOPE :
				return Direction.TOP_RIGHT;
			case SLIGHT_RISE :
				return Direction.LEFT;
			case SLIGHT_DECLINE :
				return Direction.TOP;
			case STEEP_RISE :
				return Direction.BOTTOM;
			case STEEP_DECLINE :
				return Direction.RIGHT;
			
			}
			
		case RIGHT :
			
			switch (mirrorOrientation) {
		
			case VERTICAL :
				return Direction.RIGHT;
			case HORIZONTAL :
				return null;
			case POSITIVE_SLOPE :
				return Direction.BOTTOM;
			case NEGATIVE_SLOPE :
				return Direction.TOP;
			case SLIGHT_RISE :
				return Direction.BOTTOM_LEFT;
			case SLIGHT_DECLINE :
				return Direction.TOP_LEFT;
			case STEEP_RISE :
				return Direction.BOTTOM_RIGHT;
			case STEEP_DECLINE :
				return Direction.TOP_RIGHT;
			
			}
			
		case BOTTOM_RIGHT :
			
			switch (mirrorOrientation) {
		
			case VERTICAL :
				return Direction.TOP_RIGHT;
			case HORIZONTAL :
				return Direction.BOTTOM_LEFT;
			case POSITIVE_SLOPE :
				return Direction.BOTTOM_RIGHT;
			case NEGATIVE_SLOPE :
				return null;
			case SLIGHT_RISE :
				return Direction.BOTTOM;
			case SLIGHT_DECLINE :
				return Direction.LEFT;
			case STEEP_RISE :
				return Direction.RIGHT;
			case STEEP_DECLINE :
				return Direction.TOP;
			
			}
			
		case BOTTOM :
			
			switch (mirrorOrientation) {
		
			case VERTICAL :
				return null;
			case HORIZONTAL :
				return Direction.BOTTOM;
			case POSITIVE_SLOPE :
				return Direction.RIGHT;
			case NEGATIVE_SLOPE :
				return Direction.LEFT;
			case SLIGHT_RISE :
				return Direction.BOTTOM_RIGHT;
			case SLIGHT_DECLINE :
				return Direction.BOTTOM_LEFT;
			case STEEP_RISE :
				return Direction.TOP_RIGHT;
			case STEEP_DECLINE :
				return Direction.TOP_LEFT;
			
			}
			
		case BOTTOM_LEFT :
			
			switch (mirrorOrientation) {
		
			case VERTICAL :
				return Direction.TOP_LEFT;
			case HORIZONTAL :
				return Direction.BOTTOM_RIGHT;
			case POSITIVE_SLOPE :
				return null;
			case NEGATIVE_SLOPE :
				return Direction.BOTTOM_LEFT;
			case SLIGHT_RISE :
				return Direction.RIGHT;
			case SLIGHT_DECLINE :
				return Direction.BOTTOM;
			case STEEP_RISE :
				return Direction.TOP;
			case STEEP_DECLINE :
				return Direction.LEFT;
			
			}
			
		case LEFT :
			
			switch (mirrorOrientation) {
		
			case VERTICAL :
				return Direction.LEFT;
			case HORIZONTAL :
				return null;
			case POSITIVE_SLOPE :
				return Direction.TOP;
			case NEGATIVE_SLOPE :
				return Direction.BOTTOM;
			case SLIGHT_RISE :
				return Direction.TOP_RIGHT;
			case SLIGHT_DECLINE :
				return Direction.BOTTOM_RIGHT;
			case STEEP_RISE :
				return Direction.TOP_LEFT;
			case STEEP_DECLINE :
				return Direction.BOTTOM_LEFT;
			
			}
			
		case TOP_LEFT :
			
			switch (mirrorOrientation) {
		
			case VERTICAL :
				return Direction.BOTTOM_LEFT;
			case HORIZONTAL :
				return Direction.TOP_RIGHT;
			case POSITIVE_SLOPE :
				return Direction.TOP_LEFT;
			case NEGATIVE_SLOPE :
				return null;
			case SLIGHT_RISE :
				return Direction.TOP;
			case SLIGHT_DECLINE :
				return Direction.RIGHT;
			case STEEP_RISE :
				return Direction.LEFT;
			case STEEP_DECLINE :
				return Direction.BOTTOM;
			}
			
		default : return null; // non-reachable code
	
		}
		
	}

	public MirrorOrientation getMirrorOrientation() {
		return mirrorOrientation;
	}

	public void setMirrorOrientation(MirrorOrientation mirrorOrientation) {
		this.mirrorOrientation = mirrorOrientation;
	}

	public boolean isOrientationLocked() {
		return orientationLocked;
	}

	public void setOrientationLocked(boolean orientationLocked) {
		this.orientationLocked = orientationLocked;
	}

	@Override
	public void handleClick(int button) {
		
		if (orientationLocked)
			return;
		
		switch (button) {
		case 1 : this.setMirrorOrientation(this.getMirrorOrientation().increment()); break;
		case 3 : this.setMirrorOrientation(this.getMirrorOrientation().decrement()); break;
		}
		
	}

}
